<script setup lang="ts">
import { ref, reactive, computed,nextTick,toRaw } from 'vue'
import type { FormInstance } from 'element-plus'
import { ElMessage as message, ElTree as ElTreeInstance } from 'element-plus'
import useRoleList from './roleList'
import useRouteList from '@/views/sysAuth/route/routeList'
import useRequestList from '@/views/sysAuth/request/requestList'
import { user as useUser } from '@/store'
import { listToTree, traverseTreeArr,sortTreeArr} from '@/common/utils'
import GiveAuth from './giveAuth.vue'
import MyTable from '@/components/Table/myTable.vue'
import dayjs from 'dayjs'
import {actionConfigMap,type actionKeyType} from "./roleList"


const columns: tableColConfig[] = [
	{
		label: '路由名',
		prop: 'name',
		columnKey: 'name',
		minWidth: 120,
		align: 'center',
	},
	{
		label: '接口权限',
		prop: 'accessRequestList',
		columnKey: 'accessRequestList',
		minWidth: 150,
		align: 'center',
		showOverflowTooltip: true,
		contentRender: (scope:any) => {
			if (!scope.row.component) return '无需授权'
			if (scope.row.noNeedAuth) return '具有所有权限'
			const v:requestItem[]=scope.row.accessRequestList
			if (v) {
				return v.map(i=>i.requestName).join(',')
			}
			else return ''
		},
	},
	{
		label: '按钮权限',
		prop: 'accessActionList',
		columnKey: 'accessActionList',
		minWidth: 150,
		align: 'center',
		showOverflowTooltip: true,
		contentRender: (scope:any) => {
			if (!scope.row.component) return '无需授权'
			if (scope.row.noNeedAuth) return '具有所有权限'
			const v:actionConfigType[]=scope.row.accessActionList
			if (v) {
				return v.map(i=>i.label).join(',')
			}
			else return ''
		},
	},
	{
		label: '操作',
		prop: 'operation',
		columnKey:'operation',
		fixed: 'right',
		align: 'center',
		width: 150,
	},
]
const props = defineProps<{
	editRole: { [key: string]: any }
}>()
const tableData = ref<routeTreeNode[]>([])
const formInstance = ref<FormInstance | null>(null)
const roleItem = reactive({
	roleName: '',
})
const roleList = useRoleList()
const routeList = useRouteList()
const requestList = useRequestList()
const user = useUser()
const treeData = ref<routeTreeNode[]>([])
const expandedKeys = ref<string[]>([])
const checkedKeys = ref<string[]>([])
const halfCheckedKeys = ref<string[]>([])
const parentKeys=ref<string[]>([])
const giveAuthModalVisible = ref(false)
const editNode = ref({} as routeTreeNode)
const giveAuthRef = ref<InstanceType<typeof GiveAuth>>()
const tableRef = ref<InstanceType<typeof MyTable>>()
const treeRef = ref<InstanceType<typeof ElTreeInstance>>()
const modalContentHeight = ref(300)

const formLayout = {
	style: 'margin: 0 10px',
	labelWidth: 'auto',
	labelPosition: 'left',
}

const rules = {
	roleName: [{ required: true, message: '请输入角色名！', trigger: 'change' }],
}

const _tableData = computed(() => {
	if (!tableRef.value) return []
	const pageNum = tableRef.value!.pageNum
	const pageSize = tableRef.value!.pageSize
	return JSON.parse(JSON.stringify(tableData.value)).splice((pageNum - 1) * pageSize, pageSize)
})

function showBack() {
	nextTick(() => {
		checkedKeys.value = props.editRole.checkedIds.split(',')
		// console.log(checkedKeys.value)
		halfCheckedKeys.value=props.editRole.routeIds.split(',')
    treeRef.value?.setCheckedKeys(checkedKeys.value);
		const _tableData: routeTreeNode[] = []
		traverseTreeArr(JSON.parse(JSON.stringify(treeData.value)), (v: any) => {
			if (checkedKeys.value.includes(v.id)) _tableData.push(v)
		})
		// console.log(_tableData)
		tableData.value = _tableData.map((v) => {
			delete v.children
			return v
		})
		roleItem.roleName = props.editRole.roleName
	})
}

function getTreeData(list = routeList.list) {
	const {accessRequestIds,executeAction}=props.editRole
	let executeActionMap:any
		try {
			executeActionMap=JSON.parse(executeAction)
		} catch (error) {}
  parentKeys.value=[]
	const tree = listToTree<routeTreeNode>(list, 'id', 'pId', false, (node) => {
		const _requestList = requestList.list.filter((v) => v.routeIds?.includes(String(node.id)) || !v.needAuth)
		node.requestList = _requestList
		node.accessRequestList = _requestList.filter((v) => accessRequestIds.includes(String(v.id)))
		
		if(executeActionMap && executeActionMap[node.id]) 
		node.accessActionList=executeActionMap[node.id].split(',').map((k:actionKeyType)=>actionConfigMap[k])
		//if(!node.component && !node.link) parentKeys.value.push(node.id as string)
	}) as routeTreeNode
	traverseTreeArr([tree],(v)=>{
       if(v.children && v.children.length)  parentKeys.value.push(v.id)
  })
  treeData.value = sortTreeArr([tree],'rank')
	// console.log(tree)
}

function setExpendkey() {
	expandedKeys.value=[]
	routeList.list.forEach((v) => {
		expandedKeys.value.push(...props.editRole.routeIds.split(','))
	})
}

function handleTreeCheck(node: any, { checkedKeys: _checkedKeys, checkedNodes: _checkedNodes, halfCheckedKeys: _halfCheckedKeys, halfCheckedNodes: _halfCheckedNodes }:any) {
	//console.log(_halfCheckedKeys)
	checkedKeys.value = _checkedKeys
	halfCheckedKeys.value=_halfCheckedKeys
	tableData.value = JSON.parse(JSON.stringify(_checkedNodes)).map((v: routeTreeNode) => {
		if (v.children) {
			delete v.children
		}
		return v
	})
}

function handleGiveAuth(row: routeTreeNode) {
	editNode.value = row
	giveAuthModalVisible.value = true
	nextTick(() => {
		giveAuthRef.value?.init()
	})
}

function handleGiveAuthCommit() {
	const {accessRequestList,accessActionList}=giveAuthRef.value!.formCommit()
	
	if(accessRequestList) {
    traverseTreeArr(treeData.value,(v)=>{
        v.accessRequestList=accessRequestList
				v.accessActionList=accessActionList
    },'name',editNode.value.name,)
    tableData.value.forEach(v=>{
        if(v.name==editNode.value.name) {
					v.accessRequestList=accessRequestList
					v.accessActionList=accessActionList
				}
    })
  }
	giveAuthModalVisible.value=false
}

function init() {
	formInstance.value?.resetFields();
  getTreeData()
	setExpendkey()
	showBack()
	modalContentHeight.value = Math.ceil(document.documentElement.clientHeight / 2)
}

async function formCommit() {
	try {
		await formInstance.value?.validate()
		const creator = user.info.userName
		const createdTime = dayjs(Date.now()).format('YYYY-MM-DD HH:mm:ss')
		const checkedIds:string[]=[]
		checkedKeys.value.forEach((v)=>{
			if(parentKeys.value.includes(v))
			halfCheckedKeys.value.push(v)
			else
			checkedIds.push(v)
		})
		const routeIds=[...new Set([...checkedKeys.value,...halfCheckedKeys.value])]
		if (!routeIds.length) {
			message.warning('请勾选角色具备的路由(菜单)节点')
			return
		}
		const accessRequestIds = [
			...new Set(
				tableData.value
					.filter((v) => v.accessRequestList)
					.map((v) => v.accessRequestList?.map((i) => i.id))
					.flat()
			),
		].join(',')
		const executeActionMap:objType={}
        tableData.value.filter(v=>v.accessActionList).forEach(v=>executeActionMap[v.id]=v.accessActionList?.map(v=>v.value).join(','))
		const res = await roleList.updateItem({
			...props.editRole,
			roleName: roleItem.roleName,
			creator,
			createdTime,
			checkedIds: checkedIds.join(','),
			routeIds: routeIds.join(','),
			accessRequestIds,
			id: props.editRole.id,
			executeAction:JSON.stringify(executeActionMap)
		})
		if (res.code) {
				if ((res.code = 200)) {
				if(user.info.roleIds.includes(props.editRole.id))
				return props.editRole.id
				return true
			}
			if (res.code == 201) {
				message.error('角色名已存在！')
			}
		}
	} catch (error) {
		console.log(error)
	}
}

defineExpose({
	init,
	formCommit,
})
</script>

<template>
	<el-row>
		<el-col :span="5">
			<!-- 50是表单高度 -->
			<el-scrollbar :maxHeight="modalContentHeight + 50">
				<el-tree
					:expand-on-click-node="false"
					:props="{ children: 'children', label: 'title' }"
					node-key="id"
					:data="treeData"
					:default-expanded-keys="expandedKeys"
					show-checkbox
					@check="handleTreeCheck"
					ref="treeRef"
				/>
			</el-scrollbar>
		</el-col>
		<el-col :span="19" style="padding: 0 10px">
			<el-form :model="roleItem" :rules="rules" v-bind="formLayout" ref="formInstance">
				<el-row :gutter="24">
					<el-col :span="12">
						<el-form-item name="roleName" prop="roleName" label="角色名">
							<el-input v-model="roleItem.roleName" placeholder="角色名称必须唯一" clearable />
						</el-form-item>
					</el-col>
				</el-row>
			</el-form>
			<my-table
				:data="_tableData"
				:columns="columns"
				size="small"
				style="width: 100%"
				rowKey="name"
				:maxHeight="modalContentHeight"
				:pagination="{
					pageSizes: [10, 20, 30, 40, 50],
					small: true,
					background: true,
					layout: 'total, sizes, prev, pager, next, jumper',
					total: tableData.length,
				}"
				ref="tableRef"
			>
				<template #operation="{ row }">
					<el-button type="primary" size="small" @click="handleGiveAuth(row)" :disabled="!row.component || row.noNeedAuth ? true : false">页面内权限分配</el-button>
				</template>
			</my-table>
		</el-col>
	</el-row>

	<el-dialog v-model="giveAuthModalVisible" title="页面内权限分配" width="60%" :modal="false" draggable :close-on-click-modal="false" align-center>
		<GiveAuth :editNode="editNode" ref="giveAuthRef" />
		<template #footer>
			<div class="dialog-footer">
				<el-button @click="giveAuthModalVisible = false">取消</el-button>
				<el-button type="primary" @click="handleGiveAuthCommit">确定</el-button>
			</div>
		</template>
	</el-dialog>
</template>
